﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SenseTimeTrackerForm.cs" company="BerlinSoft">
//   Wernfried Schwenkner
// </copyright>
// <summary>
//   Defines the SenseTimeTrackerForm type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;
using System.Resources;
using System.Windows.Forms;
using LunaticShade;
using SenseTimeTracker.BusinessLayer;
using SenseTimeTracker.Categories;
using SenseTimeTracker.Clients;
using SenseTimeTracker.Export;
using SenseTimeTracker.Holidays;
using SenseTimeTracker.Misc;
using SenseTimeTracker.Option;
using SenseTimeTracker.Projects;
using SenseTimeTracker.Properties;
using SenseTimeTracker.Reports;
using SenseTimeTracker.Tasks;
using SenseTimeTracker.TimeCards;
using SenseTimeTracker.Users;
using StedySoft.SenseSDK;
using StedySoft.SenseSDK.DrawingCE;

namespace SenseTimeTracker.Main
{
	public partial class SenseTimeTrackerForm : Form
	{
		private int hoverIndex = 0;
		private int lastSelectedIndex = 0;

		private SenseSlider senseSlider;
		private TransparentPanel transparentPanel;
		private SenseHeaderControl senseHeaderControl;
		private SenseListControl senseListControl;

		private List<SliderPanel> sliderPanels;

		public SenseTimeTrackerForm()
		{
			lastSelectedIndex = CheckValidUser();
			if (lastSelectedIndex == -1)
			{
				Application.Exit();
			}

			InitializeComponent();

			menuItemTimeTracker.Text = Resources.MenuItemTimeTracker;
			menuItemMenu.Text = Resources.MenuItemMenu;

			senseSlider = new SenseSlider();
			senseSlider.Dock = DockStyle.Bottom;
			senseSlider.Size = new Size(480, 84);
			senseSlider.IconSize = new Size(56, 56);
			senseSlider.OnSliding += senseSlider_OnSliding;
			senseSlider.SelectedIndexChanged += senseSlider_SelectedIndexChanged;
			senseSlider.StoppedSliding += senseSlider_StoppedSliding;
			senseSlider.StartedSliding += senseSlider_StartedSliding;

			transparentPanel = new TransparentPanel();
			transparentPanel.Alpha = 160;
			transparentPanel.BackColor = Color.Black;
			transparentPanel.Visible = false;
			transparentPanel.Paint += transparentPanel_Paint;

			senseHeaderControl = new SenseHeaderControl();
			senseHeaderControl.Dock = DockStyle.Top;

			senseListControl = new SenseListControl();
			senseListControl.Dock = DockStyle.Fill;
			senseListControl.ContextMenu = new ContextMenu();

			SuspendLayout();
			Controls.Add(transparentPanel);
			Controls.Add(senseListControl);
			Controls.Add(senseSlider);
			Controls.Add(senseHeaderControl);
			ResumeLayout(false);

			senseListControl.OnShowItemChildren += senseListControl_OnShowItemChildren;
			senseListControl.OnHideItemChildren += senseListCtrl_OnHideItemChildren;

			// Icons
			// http://www.iconarchive.com/show/scrap-icons-by-deleket/Client-icon.html
			sliderPanels = new List<SliderPanel>();
			sliderPanels.Add(new TimeCardsSliderPanel(this));
			sliderPanels.Add(new TasksSliderPanel(this));
			sliderPanels.Add(new ProjectsSliderPanel(this));
			sliderPanels.Add(new ClientsSliderPanel(this));
			sliderPanels.Add(new CategoriesSliderPanel(this));
			sliderPanels.Add(new ReportsSliderPanel(this));
			sliderPanels.Add(new UsersSliderPanel(this));
			sliderPanels.Add(new HolidaysSliderPanel(this));
			sliderPanels.Add(new OptionSliderPanel(this));

			foreach (SliderPanel sliderPanel in sliderPanels)
			{
				senseSlider.AddIcon(sliderPanel.SmallIcon);
			}

			senseSlider.SelectedIndex = lastSelectedIndex;
			
			// adjust the size of the overlay
			transparentPanel.Width = Width;
			transparentPanel.Height = Height - senseSlider.Height;
			transparentPanel.Left = 0;
			transparentPanel.Top = 0;
		}

		void senseListControl_OnShowItemChildren(SenseListControl.ISenseListItem Sender)
		{
			sliderPanels[senseSlider.SelectedIndex].senseListCtrl_OnShowItemChildren(Sender);
		}

		void senseListCtrl_OnHideItemChildren(SenseListControl.ISenseListItem Sender)
		{
			sliderPanels[senseSlider.SelectedIndex].senseListCtrl_OnHideItemChildren(Sender);
		}

		public void UpdateHeader()
		{
			senseHeaderControl.Text = sliderPanels[senseSlider.SelectedIndex].Name;
		}

		protected override void OnResize(EventArgs e)
		{
		}

		private void senseSlider_OnSliding(object sender, SenseSlider.OnSlidingEventArgs e)
		{
			// save the index under the slider
			hoverIndex = e.HoveredIndex;
			// update GUI
			transparentPanel.Refresh(); // immediately redraw overlay

			transparentPanel.Invalidate();
			transparentPanel.Update();
		}

		private void senseSlider_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (lastSelectedIndex == 6 && senseSlider.SelectedIndex != 6)
			{
				UserDisplayItem userDisplayItem = senseListControl.FocusedItem as UserDisplayItem;
				if (Persistance.Instance.UserId == Guid.Empty && userDisplayItem == null)
				{
					SenseAPIs.SenseMessageBox.Show(Resources.DialogMessageSelectUser, Resources.DialogHeaderUser, SenseMessageBoxButtons.OK);
					senseSlider.SelectedIndex = 6;
				}
				else if (userDisplayItem != null && userDisplayItem.UserId != Persistance.Instance.UserId)
				{
					using (new DialogHelper(this))
					{
						PasswordForm form = new PasswordForm
          	{
							UserName = userDisplayItem.UserName,
          	};
						if (form.ShowDialog() != DialogResult.OK)
						{
							senseSlider.SelectedIndex = 6;
						}
						else
						{
							Persistance.Instance.UserId = userDisplayItem.UserId;
						}
					}
				}
			}

			ActivateSliderPanel();
			lastSelectedIndex = senseSlider.SelectedIndex;
		}

		private void senseSlider_StartedSliding(object sender, EventArgs e)
		{
			// Darken the current page?
			// set the index under the slider
			hoverIndex = senseSlider.SelectedIndex;

			// darken background of SenseSlider
			senseSlider.BackColor = MixColors(Color.FromArgb(239, 235, 239), Color.Black, transparentPanel.Alpha);

			transparentPanel.UpdateTransparency();
			transparentPanel.Show();

			senseSlider.Refresh();
			transparentPanel.Refresh();
		}

		private void senseSlider_StoppedSliding(object sender, EventArgs e)
		{
			// Hide the overlay
			senseSlider.BackColor = Color.FromArgb(239, 235, 239);

			transparentPanel.Hide();

			// pages.Refresh();
			senseSlider.Refresh();
		}

		private void transparentPanel_Paint(object sender, PaintEventArgs e)
		{
			int w = transparentPanel.Width;
			int h = transparentPanel.Height;

			int iconW = 128;
			int iconH = 128;

			// Get the name of the page
			string s = sliderPanels[hoverIndex].Name;
			Size strSize = e.Graphics.MeasureString(s, this.Font).ToSize();

			int totalH = iconH + 10 + strSize.Height;

			// Draw the icon of the HoveredIndex (but the bigger version)
			int largeIconIndex = hoverIndex;
			if (largeIconIndex >= sliderPanels.Count)
			{
			  largeIconIndex = sliderPanels.Count - 1;
			}

			ImageAttributes immageAttr = new ImageAttributes();
			immageAttr.SetColorKey(Color.White, Color.White);
			Rectangle destRect = new Rectangle(w / 2 - iconW / 2, h / 2 - totalH / 2, iconW, iconH);
			e.Graphics.DrawImage(sliderPanels[largeIconIndex].LargeIcon, destRect, 0, 0, iconW, iconH, GraphicsUnit.Pixel, immageAttr);
			//Imaging.DrawIImage(e.Graphics, sliderPanels[largeIconIndex].LargeImage, w / 2 - iconW / 2, h / 2 - totalH / 2, iconW, iconH);

			// Draw the text
			using (Brush fc = new SolidBrush(Color.White))
				e.Graphics.DrawString(s, this.Font, fc, w / 2 - strSize.Width / 2, h / 2 + totalH / 2 - strSize.Height);
		}

		/// <summary>
		/// Mix two colors
		/// </summary>        
		private Color MixColors(Color ground, Color top, int alpha)
		{
			float a = alpha / (float)255;
			return Color.FromArgb(Mix(ground.R, top.R, a), Mix(ground.G, top.G, a), Mix(ground.B, top.B, a));
		}

		/// <summary>
		/// Mix two integers with saturation
		/// </summary>
		int Mix(int c1, int c2, float alpha)
		{
			int r = (int)((c1 * (1 - alpha) + c2 * alpha));
			return r > 255 ? 255 : r;
		}

		private int CheckValidUser()
		{
			if (Persistance.Instance.UserId == Guid.Empty)
			{
				if (User.Users.Count == 0)
				{
					SenseAPIs.SenseMessageBox.Show(Resources.DialogMessageCreateUserAccount, Resources.DialogHeaderUser, SenseMessageBoxButtons.OK);
					while (true)
					{
						using (new DialogHelper(this))
						{
							UserEditForm userEditForm = new UserEditForm
								{
									User = new User(),
								};
							if (userEditForm.ShowDialog() == DialogResult.OK)
							{
								userEditForm.User.Insert();
								Persistance.Instance.UserId = userEditForm.User.Id;
								break;
							}
							if (SenseAPIs.SenseMessageBox.Show(Resources.DialogMessageProceedCreatingAccount, Resources.DialogHeaderUser, SenseMessageBoxButtons.YesNo) == DialogResult.No)
							{
								return -1;
							}
						}
					}
				}
				else
				{
					SenseAPIs.SenseMessageBox.Show(Resources.DialogMessageSelectUser, Resources.DialogHeaderUser, SenseMessageBoxButtons.OK);
					return 6;
				}
			}

			return 0;
		}

		protected override void OnLoad(EventArgs e)
		{
			ActivateSliderPanel();
		}

		private void ActivateSliderPanel()
		{
			SliderPanel sliderPanel = sliderPanels[senseSlider.SelectedIndex];
			senseHeaderControl.Text = sliderPanel.Name;
			sliderPanel.Bind(senseListControl);
			Menu.MenuItems.Remove(menuItemMenu);
			if (sliderPanel.Menu != null)
			{
				menuItemMenu = sliderPanel.Menu;
				menuItemMenu.Popup += menuItemMenu_Popup;
				Menu.MenuItems.Add(menuItemMenu);
			}

			if (sliderPanel.ContextMenu != null)
			{
				senseListControl.ContextMenu = sliderPanel.ContextMenu;
				senseListControl.ContextMenu.Popup += menuItemMenu_Popup;
			}
		}

		private void menuItemExitTimeTracker_Click(object sender, EventArgs e)
		{
			Close();
		}

		private void menuItemExport_Click(object sender, EventArgs e)
		{
			using (new DialogHelper(this))
			{
				new ExportForm().ShowDialog();
			}
		}

		private void menuItemMenu_Popup(object sender, EventArgs e)
		{
			foreach (MenuItem menuItem in menuItemMenu.MenuItems)
			{
				menuItem.Enabled = senseListControl.FocusedItem != null || !(menuItem is CommonMenuItem && ((CommonMenuItem)menuItem).ContextSensitive);
			}

			foreach (MenuItem menuItem in senseListControl.ContextMenu.MenuItems)
			{
				menuItem.Enabled = senseListControl.FocusedItem != null || !(menuItem is CommonMenuItem && ((CommonMenuItem)menuItem).ContextSensitive);
			}
		}

		private void menuItemAboutSenseSDK_Click(object sender, EventArgs e)
		{
			SenseAPIs.SenseAboutBox.Show();
		}

		private void menuItemAboutSenseTimeTracker_Click(object sender, EventArgs e)
		{
			AboutForm form = new AboutForm();
			form.Show();
		}

		private void menuItemUpdate_Click(object sender, EventArgs e)
		{
			UpdateForm form = new UpdateForm();
			form.Show();
		}

		private void menuItemTimeTracker_Popup(object sender, EventArgs e)
		{
			menuItemExitTimeTracker.Text = Resources.MenuItemExitTimeTracker;
			menuItemExport.Text = Resources.MenuItemExport;
			menuItemAbout.Text = Resources.MenuItemAbout;
			menuItemUpdate.Text = Resources.MenuItemUpdate;
			menuItemAboutSenseSDK.Text = Resources.MenuItemAboutSenseSDK;
		}
	}
}